package link.jfire.jnet.client;

import java.nio.channels.CompletionHandler;
import link.jfire.baseutil.collection.buffer.ByteBuf;
import link.jfire.jnet.common.decodec.FrameDecodec;
import link.jfire.jnet.common.exception.BufNotEnoughException;
import link.jfire.jnet.common.exception.EndOfStreamException;
import link.jfire.jnet.common.exception.LessThanProtocolException;
import link.jfire.jnet.common.exception.NotFitProtocolException;
import link.jfire.jnet.common.handler.DataHandler;
import link.jfire.jnet.common.result.ClientInternalResult;
import link.jfire.jnet.common.result.InternalResultContainer;

public class ClientReadCompleter implements CompletionHandler<Integer, AioClient>
{
	private DataHandler[]	handlers;
	private FrameDecodec	frameDecodec;
	
	public ClientReadCompleter(FrameDecodec frameDecodec, DataHandler... handlers)
	{
		if (handlers == null || handlers.length == 0)
		{
			throw new RuntimeException("参数不能为空");
		}
		this.handlers = handlers;
		this.frameDecodec = frameDecodec;
	}
	
	@Override
	public void completed(Integer result, AioClient aioClient)
	{
		if (result == -1)
		{
			// 调用一个具体的方法将所有的future销毁
			aioClient.close(new EndOfStreamException());
			return;
		}
		ByteBuf<?> ioBuf = aioClient.ioBuf;
		ioBuf.addWriteIndex(result);
		Object decodeResult = null;
		ByteBuf<?> buf = null;
		do
		{
			try
			{
				decodeResult = buf = frameDecodec.decodec(ioBuf);
				if (decodeResult != null)
				{
					ClientInternalResult internalResult = InternalResultContainer.buildClient(decodeResult, aioClient, 0);
					for (int i = 0; i < handlers.length;)
					{
						decodeResult = handlers[i].handle(decodeResult, internalResult);
						if (i == internalResult.getIndex())
						{
							i++;
							internalResult.setIndex(i);
						}
						else
						{
							i = internalResult.getIndex();
						}
					}
					if (decodeResult != buf)
					{
						buf.release();
					}
					aioClient.popOneFuture(decodeResult);
				}
				if (ioBuf.remainRead() == 0)
				{
					aioClient.readAndWait();
					return;
				}
			}
			catch (NotFitProtocolException e)
			{
				aioClient.close(e);
				return;
			}
			catch (BufNotEnoughException e)
			{
//				ioBuf.compact();
				if (ioBuf.remainRead() < e.getNeedSize())
				{
					
					System.out.println("扩容后读取:{}" + e.getNeedSize());
				}
				ioBuf.ensureCapacity(e.getNeedSize());
				aioClient.continueRead();
				return;
			}
			catch (LessThanProtocolException e)
			{
				aioClient.readAndWait();
				return;
			}
			catch (Exception e)
			{
				aioClient.close(e);
				return;
			}
		} while (decodeResult != null);
		aioClient.readAndWait();
	}
	
	@Override
	public void failed(Throwable exc, AioClient aioClient)
	{
		// 调用一个具体的方法将所有的future销毁
		aioClient.close(exc);
	}
	
}
